using System;
using Services;
using System.IO;
using System.Linq;
using System.Threading;
using SpaceBattle.Menu;
using SpaceBattle.Resources;
using Microsoft.Xna.Framework;
using SpaceBattle.Logic.SampleLevel;
using System.IO.IsolatedStorage;
using Utilities.Menu.UIElements;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.GamerServices;

using Utilities;


namespace SpaceBattle.Menu
{
    public class CampaignNavScreen : DrawableGameComponent
    {
        ArrayList<LevelInfo> levels;
        CampaignState campaign_state;
        Model sphere;
        ArrayList<Texture2D> planets_textures;
        Matrix screen_transform, view, projection;
        SpriteBatch sprite_batch;
        Vector3 cam_init_pos;

        int focused_level = -1;
        Texture2D upper_dock, lower_dock, quit_txt;
        Button exit;
        SpriteFont font32, font18, font16;
        SoundEffect click, error;

        public CampaignNavScreen(Game game)
            : base(game)
        {
            campaign_state = Leaderboard.GetCampaignState().CampaignState;
            levels = new ArrayList<LevelInfo> { CampaignLevel.GetCampaignLevel(Math.Max(0, campaign_state.LevelPlayed - 1)), CampaignLevel.GetCampaignLevel(campaign_state.LevelPlayed)};

            if (campaign_state.LevelPlayed == 0)
                levels[0].played = false;
            else
                levels[0].played = true;

            levels[1].played = false;

            planets_textures = new ArrayList<Texture2D>(levels.Count);
            for (int i = 0; i < levels.Count; i++)
                planets_textures.Add(game.Content.Load<Texture2D>(levels[i].texture_path));

            cam_init_pos = Vector3.UnitZ * 200.0f;
            
            focused_level = 0;
            var p = levels[focused_level].position;

            view = Matrix.CreateLookAt(cam_init_pos + p, p, Vector3.Up);

            this.DrawOrder = (int)ComponentOrders.SCENE;

            game.Components.Add(new InputManager(game));            
        }

        public CampaignNavScreen(Game game, int focused_level)
            : this(game)
        {
            this.focused_level = focused_level;
        }

        InputManager input_manager;
        public override void Initialize()
        {
            var input_service = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
            input_service.OnTap += new InputManager.Tap(on_tap);

            input_manager = (InputManager)input_service;

            base.Initialize();
        }

        protected override void LoadContent()
        {
            sprite_batch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;
            screen_transform = Matrix.CreateScale(GraphicsDevice.Viewport.Width / SpaceBattleGame.DEFAULT_SCR_WIDTH, GraphicsDevice.Viewport.Height / SpaceBattleGame.DEFAULT_SCR_HEIGHT, 1.0f);

            sphere = Game.Content.Load<Model>("Planets/sphere");
            //for_each (ModelMesh m in sphere.Meshes)
            for (int i = 0; i < sphere.Meshes.Count;i++)
            {
                ModelMesh m = sphere.Meshes[i];
                //for_each (Effect fx in m.Effects)
                for(int y = 0; y < m.Effects.Count; y++)
                {
                    BasicEffect bfx = (BasicEffect)m.Effects[y];
                    bfx.EnableDefaultLighting();
                    bfx.PreferPerPixelLighting = true;
                    bfx.SpecularColor = Color.Gray.ToVector3();
                }
            }
            
            projection = Matrix.CreatePerspectiveFieldOfView(
                0.025f * (GraphicsDevice.Viewport.Width / (float)SpaceBattleGame.DEFAULT_SCR_WIDTH), 
                GraphicsDevice.Viewport.AspectRatio, 0.1f, 5000.0f);

            upper_dock = Game.Content.Load<Texture2D>("Menu/stage_dock");
            lower_dock = Game.Content.Load<Texture2D>("Menu/cs_dock");
            quit_txt = Game.Content.Load<Texture2D>("Menu/upper_right_x");
            font32 = Game.Content.Load<SpriteFont>("Fonts/OCRAExtended32");
            font18 = Game.Content.Load<SpriteFont>("Fonts/OCRAExtended18");
            font16 = Game.Content.Load<SpriteFont>("Fonts/OCRAExtended16");

            click = Game.Content.Load<SoundEffect>("Audio/button");
            error = Game.Content.Load<SoundEffect>("Audio/error");

            exit = new Button() { CollisionBox = new Rectangle(GraphicsDevice.Viewport.Width - quit_txt.Width - 10, 0, quit_txt.Width, quit_txt.Height + 10), Label = "", 
                Position = new Vector2(GraphicsDevice.Viewport.Width - quit_txt.Width, 0) };

            base.LoadContent();

            LoadingScreen.LoadProccesComplete(Game);
        }

        protected override void Dispose(bool disposing)
        {
            Game.Services.RemoveService(typeof(IInputManager));

            base.Dispose(disposing);
        }

        public Ray CalculateCursorRay(Vector2 p)
        {
            var nearPoint = GraphicsDevice.Viewport.Unproject(new Vector3(p.X, p.Y, 0), projection, view, Matrix.Identity);
            var farPoint = GraphicsDevice.Viewport.Unproject(new Vector3(p.X, p.Y, 1), projection, view, Matrix.Identity);

            return new Ray(nearPoint, Vector3.Normalize(farPoint - nearPoint));
        }

        void on_tap(Vector2 tap_position)
        {
            var p = tap_position.ToPoint(screen_transform);

            var r = CalculateCursorRay(tap_position);

            if (!camera_is_moving && levels[0].bounding_sphere.Intersects(r) != null)
            {
                if (!levels[0].played)
                {
                    click.Play(AudioManager.Volume, 0, 0);
                    StateManager.SelectCampaignShipSelection(Game);
                }
                else
                    error.Play(AudioManager.Volume, 0, 0);
            }

            if (exit.CollisionBox.Contains(p) || input_manager.IsBackButtonPressed())
            {
                click.Play(AudioManager.Volume, 0, 0);
                StateManager.SelectMenu(Game);
            }

        }

        float transition_time = 1.0f;
        float time_to_wait = 0.0f;
        bool camera_is_moving = false;
        public override void Update(GameTime gameTime)
        {
            var dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

            time_to_wait -= (dt / 5.0f);

            if (levels[focused_level].played && time_to_wait < 0)
            {
                transition_time -= dt;
                if (transition_time <= 0)
                {
                    levels.RemoveAt(0);
                    view = Matrix.CreateLookAt(cam_init_pos + levels[focused_level].position, levels[focused_level].position, Vector3.Up);
                    if (levels[0].associated_level + 1 <= CampaignMode.NUMBER_OF_LEVELS) levels.Add(CampaignLevel.GetCampaignLevel(levels[0].associated_level));
                    transition_time = 0.0f;
                    camera_is_moving = false;
                }
                else
                {
                    var v = Vector3.Lerp(levels[focused_level].position, levels[focused_level + 1].position, 1.0f - transition_time);
                    view = Matrix.CreateLookAt(cam_init_pos + v, v, Vector3.Up);
                    camera_is_moving = true;
                }
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            var time = (float)gameTime.TotalGameTime.TotalSeconds;

            sprite_batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screen_transform);

            sprite_batch.Draw(lower_dock, new Vector2(GraphicsDevice.Viewport.Width / 2.0f - lower_dock.Width / 2.0f, 
                GraphicsDevice.Viewport.Height - lower_dock.Height), Color.White);
            sprite_batch.Draw(quit_txt, exit.Position, Color.White);

            sprite_batch.DrawString(font18, "Stage: " + (levels[focused_level].associated_level)+" / 15", new Vector2(50, 20), Color.White);
            sprite_batch.DrawString(font18, "Score: " + campaign_state.Score, new Vector2(50, 60), Color.White);
            sprite_batch.DrawString(font18, "Credits: " + campaign_state.Credits, new Vector2(20, 100), Color.White);

            if (!camera_is_moving)
            { 
                var n = levels[focused_level].name;
                sprite_batch.DrawString(font18, n, new Vector2(560, GraphicsDevice.Viewport.Height / 2.0f - 
                    font18.MeasureString(n).Y / 2.0f), levels[focused_level].played ? Color.Green : Color.Red);
            }

            sprite_batch.End();

            GraphicsDevice.BlendState = BlendState.Opaque;

            for (int i = levels.Count - 1; i >= focused_level; i--)
            {
                var li = levels[i];

                for(int y = 0; y < sphere.Meshes.Count; y++)
                {
                    ModelMesh m = sphere.Meshes[y];
                    
                    for(int z=0;z<m.Effects.Count;z++)
                    {
                        var fx = (BasicEffect)m.Effects[z];
                        fx.TextureEnabled = true;
                        fx.Texture = Game.Content.Load<Texture2D>(li.texture_path);
                    }
                }

                sphere.Draw(Matrix.CreateRotationY(time) * li.world, view, projection);
            }

            base.Draw(gameTime);
        }
    }

    public static class CampaignLevel
    {
        public static ArrayList<LevelInfo> GetNewCampaignLevels()
        {
            var new_campaign_levels = new ArrayList<LevelInfo>(15);

            for (int i = 0; i < 16; i++)
            {
                new_campaign_levels.Add(GetCampaignLevel(i));    
            }

            CampaignMode.NUMBER_OF_LEVELS = new_campaign_levels.Count;

            return new_campaign_levels;
        }

        public static LevelInfo GetCampaignLevel(int index)
        {
            LevelInfo new_campaign_level = new LevelInfo();

            Vector3 v;
            Matrix w;
            BoundingSphere bs;
            ArrayList<EnemyWave> ewaves;
            int c = 0;
            string m_path, n;

            switch (index)
            {
                case 0:
                    v = Vector3.Zero; m_path = "Planets/earth"; n = "New Terra"; c = 300;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.TimeWarp}
                        }
                    };
                    break;
                case 1:
                    v = new Vector3(-5.0f, -5.0f, -4000); m_path = "Planets/mercury"; n = "Alklha"; c = 200;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke, BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.TimeWarp, BonusType.Nuke}
                        }
                    };
                    break;
                case 2:
                    v = new Vector3(5.0f, 5.0f, -8000); m_path = "Planets/io"; n = "Draugluin"; c = 350;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave {
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge }
                        },
                        new EnemyWave {
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyFighter  },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke }
                        },
                        new EnemyWave {
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.Boss1, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.TimeWarp }
                        }
                    };
                    break;
                case 3:
                    v = new Vector3(-25.0f, 25.0f, -12000); m_path = "Planets/pluto"; n = "Heyan"; c = 150;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge }
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke }
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType>()
                        }
                    };
                    break;
                case 4:
                    v = new Vector3(0.0f, 0.0f, -16000); m_path = "Planets/mars"; n = "2141 Cerberi Prime"; c = 200;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave {
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge }
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType>()
                        }
                    };
                    break;
                case 5:
                    v = new Vector3(25.0f, -12.0f, -20000); m_path = "Planets/neptune"; n = "Razentat"; c = 450;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.Boss2, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType>()
                        }
                    };
                    break;
                case 6:
                    v = new Vector3(0.0f, -20.0f, -24000); m_path = "Planets/jupiter"; n = "R'Lecth"; c = 200;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyCorvette, ShipType.EnemyDestroyer, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFrigate, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType>()
                        }
                    };
                    break;
                case 7:
                    v = new Vector3(0.0f, 10.0f, -28000); m_path = "Planets/moon"; n = "Alkonost"; c = 250;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyCorvette, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyCorvette, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyFrigate, ShipType.EnemyFighter, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFrigate, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCorvette, ShipType.EnemyCorvette, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        }
                    };
                    break;
                case 8:
                    v = new Vector3(12.0f, -19.0f, -32000); m_path = "Planets/uranus"; n = "Asherah V"; c = 550;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyCorvette, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyCorvette, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCorvette, ShipType.EnemyFighter, ShipType.EnemyFrigate, ShipType.EnemyFighter, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFrigate, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCorvette, ShipType.Boss3, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        }
                    };
                    break;
                case 9:
                    v = new Vector3(5.0f, 16.0f, -36000); m_path = "Planets/blue_saturn"; n = "New Neith"; c = 100;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyCorvette, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyCruiser, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyCorvette, ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCorvette, ShipType.EnemyCruiser, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        }
                    };
                    break;
                case 10:
                    v = new Vector3(-12.0f, -5.0f, -40000); m_path = "Planets/europa"; n = "Azunit IV"; c = 150;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyCruiser, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCorvette, ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        }
                    };
                    break;
                case 11:
                    v = new Vector3(-3.0f, 15.0f, -44000); m_path = "Planets/callisto"; n = "Ladon"; c = 250;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCorvette, ShipType.EnemyCorvette, ShipType.EnemyFrigate, ShipType.EnemyCorvette, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.EnemyCorvette, ShipType.EnemyFrigate, ShipType.EnemyFrigate },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyCruiser, ShipType.EnemyCruiser, ShipType.EnemyCruiser, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCorvette, ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFrigate, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyFrigate },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        }
                    };
                    break;
                case 12:
                    v = new Vector3(12.0f, -15.0f, -48000); m_path = "Planets/ganymede"; n = "Radarjot"; c = 650;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyFrigate, ShipType.EnemyCruiser, ShipType.EnemyFrigate, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFrigate, ShipType.EnemyCorvette, ShipType.EnemyCorvette, ShipType.EnemyFrigate },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCorvette, ShipType.EnemyCorvette, ShipType.EnemyDestroyer, ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCruiser, ShipType.EnemyCorvette, ShipType.EnemyCruiser, ShipType.EnemyCorvette, ShipType.EnemyCruiser },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFrigate, ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFrigate, ShipType.Boss4, ShipType.EnemyFrigate },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        }
                    };
                    break;
                case 13:
                    v = new Vector3(-15.0f, 8.0f, -52000); m_path = "Planets/saturn"; n = "Atlas III"; c = 500;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyCorvette, ShipType.EnemyFrigate, ShipType.EnemyCruiser },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge }
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyDestroyer, ShipType.EnemyFrigate, ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke }
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCruiser, ShipType.EnemyCorvette, ShipType.EnemyDestroyer, ShipType.EnemyCorvette, ShipType.EnemyCruiser },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCruiser, ShipType.EnemyCorvette, ShipType.EnemyBattleCruiser, ShipType.EnemyCorvette, ShipType.EnemyCruiser },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyBattleCruiser, ShipType.EnemyCruiser, ShipType.EnemyBattleCruiser, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyFrigate, ShipType.EnemyCruiser, ShipType.EnemyFrigate, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        }
                    };
                    break;
                case 14:
                    v = new Vector3(-2.0f, 5.0f, -56000); m_path = "Planets/venus"; n = "Wu-Guan-Wang"; c = 0;
                    ewaves = new ArrayList<EnemyWave> {
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyFighter, ShipType.EnemyFighter },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyDestroyer, ShipType.EnemyDestroyer, ShipType.Boss1, ShipType.EnemyDestroyer, ShipType.EnemyDestroyer },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCorvette, ShipType.EnemyCorvette, ShipType.Boss2, ShipType.EnemyCorvette, ShipType.EnemyCorvette },
                            bonuses = new ArrayList<BonusType>()
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.Boss3, ShipType.EnemyFrigate, ShipType.EnemyFrigate },
                            bonuses = new ArrayList<BonusType> { BonusType.ShieldCharge}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyFrigate, ShipType.EnemyFrigate, ShipType.Boss4, ShipType.EnemyFrigate, ShipType.EnemyFrigate },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { ShipType.EnemyCruiser, ShipType.EnemyCruiser, ShipType.Boss5, ShipType.EnemyCruiser, ShipType.EnemyCruiser },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        },
                        new EnemyWave { 
                            ships = new ArrayList<ShipType> { 
                                ShipType.EnemyBattleCruiser, ShipType.EnemyBattleCruiser, ShipType.Boss6, 
                                ShipType.EnemyBattleCruiser, ShipType.EnemyBattleCruiser },
                            bonuses = new ArrayList<BonusType> { BonusType.Nuke}
                        }
                    };
                    break;
                default:
                    v = Vector3.Zero; m_path = ""; n = "";
                    ewaves = new ArrayList<EnemyWave>();
                    break;
            }

            bs = new BoundingSphere(v, 1); 
            w = Matrix.CreateTranslation(v);

            return new_campaign_level = new LevelInfo { associated_level = index + 1, position = v, 
                enemy_waves = ewaves, played = false, texture_path = m_path, bounding_sphere = bs, world = w, 
                name = n, given_credits = c };
        }
    }

    public class LevelInfo
    {
        public Vector3 position;
        public Matrix world;
        public BoundingSphere bounding_sphere;
        public string texture_path;
        public int associated_level;
        public int given_credits;
        public ArrayList<EnemyWave> enemy_waves;
        public bool played;
        public string name;
    }

    public class EnemyWave
    {
        public ArrayList<ShipType> ships;
        public ArrayList<BonusType> bonuses;
    }
}
